package com.tongji.diy.model.furniturePlacementOptimization
{
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Bedding;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.BeddingBlock;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.ConversationBlock;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Facal;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FacalChildBlock;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FurnitureBase;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Seat;
	import com.tongji.diy.utils.OptimizationMath;
	
	import flash.geom.Point;
	import flash.geom.Vector3D;

	public class ConstructorCompound
	{
		private var data:DataAndFunction;
		public function ConstructorCompound(data:DataAndFunction)
		{
			this.data = data;
			main();
		}
		
		private function main():void
		{
			//data._aganistWallList = buildAnganistWallList();
			facalCompound();
			
			var collisionRoom:Boolean = false;
			while(data._furnitureBlock && !collisionRoom)
			{
				//var v:Vector3D = data.searchLocationWall(data._furnitureBlock,Math.random());
				if(data.symetrySign)
					var v:Vector3D = data.searchLocationWall(data._furnitureBlock,data.noNearBoarderRandNum());
				else
					v = data.searchLocationWall(data._furnitureBlock,Math.random());
				data._furnitureBlock.x = v.x;
				data._furnitureBlock.y = v.y;
				data._furnitureBlock.angle =v.z;
				
				if(data.boundingBoxInRoom(data._furnitureBlock.boundingBox, data._room))
				{
					collisionRoom = true;
				}
			}
			
			if(!data._furnitureBlock && data._beddingList.length)
			{
				beddingCompound();
			}
			else if(!data._furnitureBlock && data._seatList.length)
			{
				seatCompound();
			}
			//将accessiblebox加入到该模块的bondingbox中
			if(data._furnitureBlock && data._furnitureBlock.accessibleBox)
			{
				data._boundBoxes.push(data._furnitureBlock.accessibleBox);
			}
		}
		
		private function beddingCompound():void
		{
			data._furnitureBlock = new BeddingBlock(-1,-1,true,data._beddingList);
			if(data.symetrySign)
				var v:Vector3D = data.searchLocationWall(null,data.noNearBoarderRandNum(), (data._furnitureBlock as BeddingBlock).width, (data._furnitureBlock as BeddingBlock).length);
			else
				v = data.searchLocationWall(null,Math.random(), (data._furnitureBlock as BeddingBlock).width, (data._furnitureBlock as BeddingBlock).length);
			data._furnitureBlock.x = v.x;
			data._furnitureBlock.y = v.y;
			data._furnitureBlock.angle = v.z;			
		}
		
		private function seatCompound():void
		{
			data._furnitureBlock = new ConversationBlock(-1,-1,true,data._seatList);
			if(data.symetrySign)
				var v:Vector3D = data.searchLocationWall(null,data.noNearBoarderRandNum(), (data._furnitureBlock as ConversationBlock).width, (data._furnitureBlock as ConversationBlock).length);
			else
				v = data.searchLocationWall(null,Math.random(), (data._furnitureBlock as ConversationBlock).width, (data._furnitureBlock as ConversationBlock).length);
			data._furnitureBlock.x = v.x;
			data._furnitureBlock.y = v.y;
			data._furnitureBlock.angle = v.z;
		}
		
		
		private function facalCompound():void
		{
			var v:Vector.<FurnitureBase> = new Vector.<FurnitureBase>;
			//找到facal
			var furV:Vector.<FurnitureBase>  = data._block.filter(facalExist);
			var beddingExist:Boolean = false;
			
			if(furV && furV.length)
			{
				OptimizationMath.assert(furV.length == 1);
				
				var facal:Facal = furV.shift() as Facal;
				
				facal.location = new Point(0,0);
				for(var i:int = 0; i < facal.visibleOrientation.length; ++i)
				{
					if(facal.visibleOrientation[i])
					{
						var seatv:Vector.<FurnitureBase> = findSeat(facal.correspondingNumVector[i]);
						
						if(!seatv || !seatv.length)
						{
							var beddingv:Vector.<FurnitureBase> = findBedding(facal.correspondingNumVector[i]);
							tempv = symmetricAssign(beddingv,facal,i);
							beddingExist = true;
						}
						else
							var tempv:Vector.<FurnitureBase> = symmetricAssign(seatv,facal,i);
						while(tempv && tempv.length)
							v.push(tempv.shift());
					}
				}
				v.push(data._block.splice(data._block.indexOf(facal),1).shift());
				data._furnitureBlock = new FacalChildBlock(v);
				if(beddingExist)
					(data._furnitureBlock as FacalChildBlock).mirrorRotate();
			}
			else
				return;			
		}

		private function symmetricAssign(furv:Vector.<FurnitureBase>, facal:Facal, orentation:int):Vector.<FurnitureBase>
		{
			if(!furv.length)
				return null;
			//计算出对应的furniture的总长度,将来建议使用assiblebox的width代替
			var width:Number = 0;
			var length:Number = 0;
			for (var i:int = 0; i < furv.length; ++i)
			{
				width += furv[i].width;
				length += furv[i].length;
			}
			
			
			if(orentation == 0 || orentation == 1)
			{
				if(width > facal.width)
				{
					var tempx:Number = facal.x - width / 2;
					if(orentation == 1)
						var tempy:Number = facal.y + facal.length/2 +facal.visibleDistance[orentation];
					else
						tempy = facal.y - facal.length/2 - facal.visibleDistance[orentation];
					
					for(i = 0; i < furv.length; ++i)
					{
						furv[i].x = tempx + furv[i].width / 2;
						if(orentation == 1)
						{
							furv[i].y = tempy + furv[i].length / 2;
							furv[i].angle = 0;
						}
						else
						{
							furv[i].y = tempy - furv[i].length / 2;
							furv[i].angle = Math.PI;
						}
						
						tempx += furv[i].width;
					}		
				}
				else
				{
					if(furv.length > 1)
					{
						var border:Number = (facal.width - width) / (furv.length - 1);
						tempx = facal.x - facal.width/2;
						if(orentation == 1)
							tempy = facal.y + facal.length/2 + facal.visibleDistance[orentation];
						else
							tempy = facal.y - facal.length/2 - facal.visibleDistance[orentation];
						for(i = 0; i < furv.length; ++i)
						{
							furv[i].x = tempx + furv[i].width / 2;
							if(orentation == 1)
							{
								furv[i].y = tempy + furv[i].length / 2;
								furv[i].angle = 0;
							}
							else
							{
								furv[i].y = tempy - furv[i].length / 2;
								furv[i].angle = Math.PI;
							}
							tempx += furv[i].width + border;
						}							
					}
					else
					{
						furv[0].x = facal.x;
						if(orentation == 1)
						{
							furv[0].y = facal.y + facal.length / 2 + facal.visibleDistance[orentation] + furv[0].length / 2;
							furv[0].angle = 0;
						}
						else
						{
							furv[0].y = facal.y - facal.length / 2 - facal.visibleDistance[orentation] - furv[0].length / 2;
							furv[0].angle = Math.PI;
						}
					}
				}
				
			}
				//ortentaion == 2 or 3 即左右的方向
			else
			{
				if(length > facal.length)
				{
					tempy = facal.y - length / 2;
					if(orentation == 3)
						tempx = facal.x + facal.width/2 + facal.visibleDistance[orentation];
					else
						tempx = facal.x - facal.width/2 - facal.visibleDistance[orentation];
					
					for(i = 0; i < furv.length; ++i)
					{
						furv[i].y = tempy + furv[i].length / 2;
						if(orentation == 3)
						{
							furv[i].x = tempx + furv[i].width / 2;
							furv[i].angle = +Math.PI/2;
						}
						else
						{
							furv[i].x = tempx - furv[i].width / 2;
							furv[i].angle = -Math.PI/2;
						}
						
						tempy += furv[i].length;
					}		
				}
				else
				{
					if(furv.length > 1)
					{
						border = (facal.length - length) / (furv.length - 1);
						tempy = facal.y - facal.length/2;
						if(orentation == 3)
							tempx = facal.x + facal.width/2 + facal.visibleDistance[orentation];
						else
							tempx = facal.x - facal.width/2 - facal.visibleDistance[orentation];
						for(i = 0; i < furv.length; ++i)
						{
							furv[i].y = tempy + furv[i].length / 2;
							if(orentation == 3)
							{
								furv[i].x = tempx + furv[i].width / 2;
								furv[i].angle = +Math.PI/2;
							}
							else
							{
								furv[i].x = tempx - furv[i].width / 2;
								furv[i].angle = -Math.PI/2;
							}
							tempy += furv[i].length + border;
						}							
					}
					else
					{
						furv[0].y = facal.y;
						if(orentation == 3)
						{
							furv[0].x = facal.x + facal.width / 2 + facal.visibleDistance[orentation] + furv[0].width / 2;
							furv[0].angle = +Math.PI/2;
						}
						else
						{
							furv[0].x = facal.x - facal.width / 2 - facal.visibleDistance[orentation] - furv[0].width / 2;
							
							furv[0].angle = -Math.PI/2;
						}
					}
				}
			}
			
			
			return furv;
		}
		
		private function findBedding(corrNum:Number):Vector.<FurnitureBase>
		{
			var result:Vector.<FurnitureBase> = new Vector.<FurnitureBase>;
			var fur:FurnitureBase;
			var tempNum:Number = 0;
			
			var sign:Boolean = false;
			while(corrNum > 0 && (!sign || fur != null))
			{
				sign = true;
				fur = null;
				tempNum = 0;
				data._block.forEach(findBeddingForEach);
				corrNum -= tempNum;
				if(fur != null)
				{
					OptimizationMath.assert(fur != null);
					result.push(data._block.splice(data._block.indexOf(fur),1).shift());
				}
			}
			
			return result;
			
			function findBeddingForEach(item:Object, index:int, v:*):void
			{
				if((item is Bedding) && (item as Bedding).peopleNum <= corrNum && (tempNum < (item as Bedding).peopleNum))
				{
					tempNum = (item as Bedding).peopleNum;
					fur = item as FurnitureBase;
				}
			}
		}
		
		
		private function findSeat(corrNum:Number):Vector.<FurnitureBase>
		{
			var result:Vector.<FurnitureBase> = new Vector.<FurnitureBase>;
			var fur:FurnitureBase;
			var tempNum:Number = 0;
			
			var sign:Boolean = false;
			while(corrNum > 0 && (!sign || fur != null))
			{
				sign = true;
				fur = null;
				tempNum = 0;
				data._block.forEach(findSeatForEach);
				corrNum -= tempNum;
				if(fur != null)
				{
					OptimizationMath.assert(fur != null);
					result.push(data._block.splice(data._block.indexOf(fur),1).shift());
				}
			}
			
			
			
			return result;
			function findSeatForEach(item:Object, index:int, v:*):void
			{
				if((item is Seat) && (item as Seat).peopleNum <= corrNum && (tempNum < (item as Seat).peopleNum))
				{
					tempNum = (item as Seat).peopleNum;
					fur = item as FurnitureBase;
				}
			}
		}
		
		
		private function facalExist(item:Object, index:int, v:*):Boolean
		{
			if(item is Facal)
				return true;
			else
				return false;
		}
		
	}
}